<template>
  <div>
    <el-form-item :label-width="item.labelWidth?item.labelWidth:'130px'" :label="item.title" :prop="rules?item.field:''">
      <!-- <el-input v-model="form[item.field]" :disabled="disabled" @change="change"></el-input> -->
      <span slot="label">{{item.title}}
        <el-tooltip v-if="item.info" :content="item.info" placement="top">
          <span class="fas fa-info-circle color"></span>
        </el-tooltip>
      </span>
      <div >
        <el-upload
          v-if="!disabled"
          class="upload-demo"
          ref="upload"
          :multiple="item.multiple?item.multiple: false"
          action="http://127.0.0.1:8080/docmanager/upload"
          :http-request = "customUpload"
          :on-preview="onPreview"
          :accept = "item.accept"
          :file-list="fileList"
          :limit="item.limit"
          :disabled="disabled"
          :on-exceed="onExceed"
          :show-file-list="false"
          :auto-upload="true">
          <el-button  slot="trigger" size="small" type="primary" >选取文件</el-button>
          <!-- <el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">上传到服务器</el-button> -->
        </el-upload>
        <div v-if="!disabled">
          <div v-for="(item,index) in this.form[this.item.field]" :key="item.path" class="file-item relative" :title="item.docName" @click="doDownLoad(item)">
            <span  ><span class="fas fa-file-alt color padding-r"></span><span class="doc-name">{{item.docName}}</span></span>
            <div title="删除" class="file-close" @click.stop="deleteFile(index)"><img src="../../../../assets/beneform4j/icon/home_icon_delete.png" alt=""></div>
          </div>
          <div v-if="this.form[this.item.field] && this.form[this.item.field].length == 0" class="none-file">
            -- 暂无附件 --
          </div>
        </div>
        <div v-if="disabled">
          <div v-for="(item,index) in this.form[this.item.field]" :key="item.docId" class="file-item relative" :title="item.docName" @click="doDownLoad(item)">
            <span ><span class="fas fa-file-alt color padding-r"></span><span class="doc-name">{{item.docName}}</span></span>
          </div>
          <div v-if="this.form[this.item.field] && this.form[this.item.field].length == 0" class="none-file">
            -- 暂无附件 --
          </div>
        </div>
      </div>
    </el-form-item>
  </div>
</template>

<script>
/**
 * multiple	是否支持多选文件
 * data	上传时附带的额外参数
 * show-file-list	是否显示已上传文件列表
 * accept	接受上传的文件类型（thumbnail-mode 模式下此参数无效）
 *
 * on-preview	点击文件列表中已上传的文件时的钩子
 * on-remove	文件列表移除文件时的钩子
 * on-success	文件上传成功时的钩子
 * on-error	文件上传失败时的钩子
 * on-progress	文件上传时的钩子
 * on-change	文件状态改变时的钩子，添加文件、上传成功和上传失败时都会被调用
 * before-upload	上传文件之前的钩子，参数为上传的文件，若返回 false 或者返回 Promise 且被 reject，则停止上传。
 * before-remove	删除文件之前的钩子，参数为上传的文件和文件列表，若返回 false 或者返回 Promise 且被 reject，则停止上传
 *
 * list-type	文件列表的类型
 * auto-upload	是否在选取文件后立即进行上传
 * file-list	上传的文件列表, 例如: [{name: 'food.jpg', url: 'https://xxx.cdn.com/xxx.jpg'}]
 * http-request	覆盖默认的上传行为，可以自定义上传的实现
 * disabled	是否禁用
 * limit	最大允许上传个数
 * on-exceed	文件超出个数限制时的钩子
 *
 */
import SparkMD5 from 'spark-md5';
import { fileUpload, getFilesListApi } from '../../../api/common';
export default {
  props: ['item', 'form', 'rules', 'disabled'],
  data() {
    return {
      fileList: [], // 上传的文件列表
      files: [] // 上传成功文件列表
    };
  },
  mounted(){
    // console.log(this.item)
    const busiKey = this.item.busiKey
    if (busiKey) {
      if (!this.form[busiKey]) {
        return
      }
      const params = {
        busiKey: this.form[busiKey],
        busiFunc: this.item.busiFunc ? this.item.busiFunc : this.form.busiFunc
      }
      this.$set(this.form, this.item.field, [])
      getFilesListApi(params).then(response => {
        if(response.success) {
          this.form[this.item.field] = response.data
        }
      })
    }
  },
  methods: {
    doDownLoad(item) {
      if (item.path) {
        this.downloadByPath(item.path, item.docName)
      } else {
        this.downloadByPath(item.storePath, item.docName)
      }
    },
    deleteFile(index) {
      this.form[this.item.field].splice(index, 1);
    },
    change(v) {
      if (this.item.itemChange) {
        this.item.itemChange(this.form, this.item, v);
      }
    },
    customUpload(file) {
      /**
       * 方案：一
       * 1 生成MD5
       * 2 提交MD5到后端验证文件是否已经存在
       *   否 上传文件到服务器
       *   是 不上传文件
       * 3 点击保存按钮，提交MD5值
       * 方案：二
       * 同时上传文件和MD5
       *
       * 采取方案二进行开发
       */
      const fileSize = file.file.size / 1024 / 1024// 文件大小控制60M
      if (fileSize > 60) {
        this.$message.error('上传文件大小不能超过 60MB!')
        return
      }
      this.generatorFileMd5(file, fileUpload)
    },
    submitUpload() {
      // 上传
      this.$refs.upload.submit();
    },
    onPreview(file) {
      const fileMD5 = file.raw._MD5;
      // console.log(file)
      const fields = [
        {
          name: 'docId',
          value: fileMD5
        },
        {
          name: '_token',
          value: sessionStorage.getItem('Admin-Token')
        }
      ];
      const form = document.createElement('form');
      form.action = process.env.BASE_API + '/docmanager/download';
      form.mehod = 'GET';
      form.target = 'downloadFrame';

      for (let i = 0, l = fields.length; i < l; i++) {
        const field = fields[i];
        const f = document.createElement('input');
        f.type = 'hidden';
        f.name = field.name;
        f.value = field.value;
        form.appendChild(f);
      }
      document.body.appendChild(form);
      form.submit();
      document.body.removeChild(form);
    },
    downloadByPath(path, name) {
      const fields = [
        {
          name: 'docName',
          value: name,
        },
        {
          name: 'path',
          value: path
        },
        {
          name: '_token',
          value: sessionStorage.getItem('Admin-Token')
        }
      ];
      const form = document.createElement('form');
      form.action = process.env.BASE_API + '/docmanager/download';
      form.mehod = 'GET';
      form.target = 'downloadFrame';

      for (let i = 0, l = fields.length; i < l; i++) {
        const field = fields[i];
        const f = document.createElement('input');
        f.type = 'hidden';
        f.name = field.name;
        f.value = field.value;
        form.appendChild(f);
      }
      document.body.appendChild(form);
      form.submit();
      document.body.removeChild(form);
    },
    onExceed() {
      this.$message({
        message: '限制只能上传' + this.item.limit + '个文件',
        type: 'error'
      });
    },
    generatorFileMd5(fileObj, fileUpload) {
      /**
       * 生成MD5
       */
      const file = fileObj.file;
      const blobSlice =
        File.prototype.slice ||
        File.prototype.mozSlice ||
        File.prototype.webkitSlice;
      const chunkSize = 2097152; // Read in chunks of 2MB
      const chunks = Math.ceil(file.size / chunkSize);
      let currentChunk = 0;
      const spark = new SparkMD5.ArrayBuffer();
      const fileReader = new FileReader();
      const me = this
      fileReader.onload = (e) => {
        spark.append(e.target.result) // Append array buffer
        currentChunk++;
        if (currentChunk < chunks) {
          loadNext();
        } else {
          // console.log(spark.end()) // spark.end(): 文件 MD5值生成完成
          const MD5 = spark.end();
          fileObj.file._MD5 = MD5;
          fileUpload(fileObj, MD5).then(response => {
            if (response.success) {
              const fileObj = {
                docName: response.data.docName,
                path: response.data.storePath,
                docId: MD5
              }
              // 去重
              const fileIdObj = {}
              if (!me.form[me.item.field]){
                this.$set(me.form, me.item.field, [])
              }
              me.form[me.item.field].forEach(v => {
                fileIdObj[v.docId] = true
              })
              if (fileIdObj[fileObj.docId]) {
                this.$message({
                  message: fileObj.docName + '文件已经上传，请勿重复提交',
                  type: 'error'
                });
                return
              }
              me.form[me.item.field].push(fileObj)
            }
          });
        }
      };

      fileReader.onerror = function() {
        console.warn('fileReader.onerror is error');
      };

      function loadNext() {
        const start = currentChunk * chunkSize;
        const end =
          start + chunkSize >= file.size ? file.size : start + chunkSize;
        fileReader.readAsArrayBuffer(blobSlice.call(file, start, end));
      }
      loadNext();
    }
  }
};
</script>

<style scoped>
.file-close {
  position: absolute;
  right: 0px;
  top: 0;
  width: 16px;
  text-align: center;
  background: #fff;
}
.file-item {
  cursor: pointer;
  padding: 0 10px;
  padding-right: 16px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-bottom: 1px solid transparent;
}
.doc-name{
  margin-right: 16px;
}
.file-item:hover .doc-name {
  border-bottom: 1px solid #0099ff;
  color: #0099ff;
}
.none-file{
  color: #aaa;
}
</style>
